-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[C] Do not diagnose flexible array members with -Wdefault-const-init-field-unsafe #140578
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[C] Do not diagnose flexible array members with -Wdefault-const-init-field-unsafe #140578
Conversation
…field-unsafe This addresses post-commit review feedback from someone who discovered that we diagnosed code like the following: struct S { int len; const char fam[]; } s; despite it being invalid to initialize the flexible array member. Note, this applies to flexible array members and zero-sized arrays at the end of a structure (an old-style flexible array member), but it does not apply to one-sized arrays at the end of a structure because those do occupy storage that can be initialized.
@llvm/pr-subscribers-clang Author: Aaron Ballman (AaronBallman) ChangesThis addresses post-commit review feedback from someone who discovered that we diagnosed code like the following:
despite it being invalid to initialize the flexible array member. Note, this applies to flexible array members and zero-sized arrays at the end of a structure (an old-style flexible array member), but it does not apply to one-sized arrays at the end of a structure because those do occupy storage that can be initialized. Full diff: https://github.com/llvm/llvm-project/pull/140578.diff 2 Files Affected:
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 9ee8603ff7811..e17e68966dc00 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -6513,6 +6513,14 @@ static bool canPerformArrayCopy(const InitializedEntity &Entity) {
static const FieldDecl *getConstField(const RecordDecl *RD) {
assert(!isa<CXXRecordDecl>(RD) && "Only expect to call this in C mode");
for (const FieldDecl *FD : RD->fields()) {
+ // If the field is a flexible array member, we don't want to consider it
+ // as a const field because there's no way to initialize the FAM anyway.
+ if (Decl::isFlexibleArrayMemberLike(
+ FD->getASTContext(), FD, FD->getType(),
+ LangOptions::StrictFlexArraysLevelKind::ZeroOrIncomplete,
+ /*IgnoreTemplateOrMacroSubstitution=*/true))
+ continue;
+
QualType QT = FD->getType();
if (QT.isConstQualified())
return FD;
diff --git a/clang/test/Sema/warn-default-const-init.c b/clang/test/Sema/warn-default-const-init.c
index e788d72899685..e6ff0aa783e23 100644
--- a/clang/test/Sema/warn-default-const-init.c
+++ b/clang/test/Sema/warn-default-const-init.c
@@ -85,3 +85,33 @@ void func() {
static const int b; // zero-init-var-warning {{default initialization of an object of type 'const int' is incompatible with C++}} \
cxx-error {{default initialization of an object of const type 'const int'}}
}
+
+// Test the behavior of flexible array members. Those cannot be initialized
+// when a stack-allocated object of the structure type is created. We handle
+// degenerate flexible arrays similarly, but only if the array does not
+// actually specify any storage. Note that C++ does not have flexible array
+// members at all, which is why the test is disabled there.
+#ifndef __cplusplus
+struct RealFAM {
+ int len;
+ const char fam[];
+};
+
+struct FakeFAM {
+ int len;
+ const char fam[0];
+};
+
+struct NotTreatedAsAFAM {
+ int len;
+ const char fam[1]; // unsafe-field-note {{member 'fam' declared 'const' here}} \
+ unsafe-field-compat-note {{member 'fam' declared 'const' here}}
+};
+
+void test_fams() {
+ struct RealFAM One;
+ struct FakeFAM Two;
+ struct NotTreatedAsAFAM Three; // unsafe-field-warning {{default initialization of an object of type 'struct NotTreatedAsAFAM' with const member leaves the object uninitialized}} \
+ unsafe-field-compat-warning {{default initialization of an object of type 'struct NotTreatedAsAFAM' with const member leaves the object uninitialized and is incompatible with C++}}
+}
+#endif // !defined(__cplusplus)
|
…field-unsafe (llvm#140578) This addresses post-commit review feedback from someone who discovered that we diagnosed code like the following: ``` struct S { int len; const char fam[]; } s; ``` despite it being invalid to initialize the flexible array member. Note, this applies to flexible array members and zero-sized arrays at the end of a structure (an old-style flexible array member), but it does not apply to one-sized arrays at the end of a structure because those do occupy storage that can be initialized.
This addresses post-commit review feedback from someone who discovered that we diagnosed code like the following:
despite it being invalid to initialize the flexible array member.
Note, this applies to flexible array members and zero-sized arrays at the end of a structure (an old-style flexible array member), but it does not apply to one-sized arrays at the end of a structure because those do occupy storage that can be initialized.